package cn.com.anypay.manager.config;

import cn.com.anypay.manager.dto.config.WeChatAuthConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;

/**
 * 微信API调用RestTemplate配置
 * 专门用于微信API调用的HTTP客户端配置，包含超时、重试和日志记录
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class WeChatRestTemplateConfig {
    
    private final WeChatAuthConfig weChatAuthConfig;
    
    /**
     * 创建专用于微信API调用的RestTemplate
     * 配置了超时时间、连接池和请求拦截器
     */
    @Bean("weChatRestTemplate")
    public RestTemplate weChatRestTemplate(RestTemplateBuilder builder) {
        // 创建HTTP客户端请求工厂
        ClientHttpRequestFactory requestFactory = createHttpRequestFactory();
        
        RestTemplate restTemplate = builder
                // 设置请求工厂
                .requestFactory(() -> requestFactory)
                // 添加请求拦截器用于日志记录
                .interceptors(weChatApiLoggingInterceptor())
                // 构建RestTemplate
                .build();
        
        log.info("微信API RestTemplate配置完成 - 超时时间: {}ms, 重试次数: {}", 
                weChatAuthConfig.getTimeout(), weChatAuthConfig.getRetryCount());
        
        return restTemplate;
    }
    
    /**
     * 创建HTTP客户端请求工厂
     * 配置超时时间等网络参数
     */
    private ClientHttpRequestFactory createHttpRequestFactory() {
        // 使用简单的HTTP客户端请求工厂
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        
        // 设置连接超时时间
        factory.setConnectTimeout(weChatAuthConfig.getTimeout());
        
        // 设置读取超时时间
        factory.setReadTimeout(weChatAuthConfig.getTimeout());
        
        // 设置缓冲请求体（用于重试）
        factory.setBufferRequestBody(true);
        
        log.debug("HTTP客户端请求工厂创建完成 - 连接超时: {}ms, 读取超时: {}ms", 
                weChatAuthConfig.getTimeout(), weChatAuthConfig.getTimeout());
        
        return factory;
    }
    
    /**
     * 微信API调用日志拦截器
     * 记录请求和响应信息，用于监控和调试
     */
    private ClientHttpRequestInterceptor weChatApiLoggingInterceptor() {
        return (request, body, execution) -> {
            long startTime = System.currentTimeMillis();
            String requestId = generateRequestId();
            
            // 记录请求信息（脱敏处理）
            String uri = request.getURI().toString();
            String sanitizedUri = sanitizeUri(uri);
            String apiName = extractApiName(uri);
            
            log.info("微信API请求开始 [{}] - API: {}, 方法: {}, URL: {}", 
                    requestId, apiName, request.getMethod(), sanitizedUri);
            
            // 记录请求体大小（如果有）
            if (body != null && body.length > 0) {
                log.debug("微信API请求体大小 [{}]: {} bytes", requestId, body.length);
            }
            
            // 记录请求头（调试模式）
            if (log.isDebugEnabled()) {
                log.debug("微信API请求头 [{}]: {}", requestId, sanitizeHeaders(request.getHeaders().toString()));
            }
            
            ClientHttpResponse response = null;
            try {
                // 执行请求
                response = execution.execute(request, body);
                
                long duration = System.currentTimeMillis() - startTime;
                int statusCode = response.getStatusCode().value();
                
                // 记录响应信息
                log.info("微信API请求完成 [{}] - API: {}, 状态码: {}, 耗时: {}ms", 
                        requestId, apiName, statusCode, duration);
                
                // 记录响应头（调试模式）
                if (log.isDebugEnabled()) {
                    log.debug("微信API响应头 [{}]: {}", requestId, response.getHeaders());
                }
                
                // 记录性能警告
                if (duration > 3000) {
                    log.warn("微信API响应较慢 [{}] - API: {}, 耗时: {}ms", requestId, apiName, duration);
                } else if (duration > 5000) {
                    log.error("微信API响应超时风险 [{}] - API: {}, 耗时: {}ms", requestId, apiName, duration);
                }
                
                // 记录HTTP状态码警告
                if (statusCode >= 400) {
                    log.warn("微信API返回错误状态码 [{}] - API: {}, 状态码: {}", requestId, apiName, statusCode);
                }
                
                return response;
                
            } catch (IOException e) {
                long duration = System.currentTimeMillis() - startTime;
                
                log.error("微信API请求异常 [{}] - API: {}, 错误类型: {}, 错误信息: {}, 耗时: {}ms", 
                        requestId, apiName, e.getClass().getSimpleName(), e.getMessage(), duration);
                
                // 记录网络相关的详细错误信息
                if (e.getMessage() != null) {
                    if (e.getMessage().contains("timeout")) {
                        log.error("微信API请求超时 [{}] - API: {}, 配置超时时间: {}ms", 
                                requestId, apiName, weChatAuthConfig.getTimeout());
                    } else if (e.getMessage().contains("Connection refused")) {
                        log.error("微信API连接被拒绝 [{}] - API: {}, 请检查网络连接", requestId, apiName);
                    } else if (e.getMessage().contains("UnknownHostException")) {
                        log.error("微信API域名解析失败 [{}] - API: {}, 请检查DNS配置", requestId, apiName);
                    }
                }
                
                throw e;
            }
        };
    }
    
    /**
     * 生成请求ID用于日志追踪
     */
    private String generateRequestId() {
        return "WX" + System.currentTimeMillis() + Thread.currentThread().getId();
    }
    
    /**
     * 从URL中提取API名称
     */
    private String extractApiName(String url) {
        if (url == null) {
            return "unknown";
        }
        
        if (url.contains("oauth2/access_token")) {
            return "getAccessToken";
        } else if (url.contains("sns/userinfo")) {
            return "getUserInfo";
        } else if (url.contains("oauth2/refresh_token")) {
            return "refreshToken";
        } else if (url.contains("qrconnect")) {
            return "authorize";
        } else {
            return "unknown";
        }
    }
    
    /**
     * 对请求头进行脱敏处理
     */
    private String sanitizeHeaders(String headers) {
        if (headers == null) {
            return null;
        }
        
        // 隐藏Authorization头
        headers = headers.replaceAll("Authorization=[^,\\]]*", "Authorization=***");
        
        // 隐藏其他敏感头信息
        headers = headers.replaceAll("Cookie=[^,\\]]*", "Cookie=***");
        
        return headers;
    }
    
    /**
     * 对URI进行脱敏处理，隐藏敏感信息
     * 
     * @param uri 原始URI
     * @return 脱敏后的URI
     */
    private String sanitizeUri(String uri) {
        if (uri == null) {
            return null;
        }
        
        // 隐藏access_token参数
        uri = uri.replaceAll("access_token=[^&]*", "access_token=***");
        
        // 隐藏secret参数
        uri = uri.replaceAll("secret=[^&]*", "secret=***");
        
        // 隐藏refresh_token参数
        uri = uri.replaceAll("refresh_token=[^&]*", "refresh_token=***");
        
        // 隐藏code参数（部分隐藏）
        uri = uri.replaceAll("code=([^&]{10})[^&]*", "code=$1***");
        
        return uri;
    }
}